home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectInput / DIConfig / cfrmwrk.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-08  |  6.4 KB  |  261 lines

  1. //-----------------------------------------------------------------------------
  2. // File: cfrmwrk.cpp
  3. //
  4. // Desc: CDirectInputActionFramework is the outer-most layer of the UI. It
  5. //       contains everything else. Its functionality is provided by one
  6. //       method: ConfigureDevices.
  7. //
  8. //       InternalConfigureDevices is called by the CDirectInputActionFramework
  9. //       class. This function actually contains the initialization code and
  10. //       the message pump for the UI.
  11. //
  12. // Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
  13. //-----------------------------------------------------------------------------
  14.  
  15. #include "common.hpp"
  16.  
  17.  
  18. //QueryInterface
  19. STDMETHODIMP CDirectInputActionFramework::QueryInterface(REFIID iid, LPVOID* ppv)
  20. {
  21.     //null the out param
  22.     *ppv = NULL;
  23.  
  24.     if ((iid == IID_IUnknown) || (iid == IID_IDIActionFramework))
  25.     {
  26.         *ppv = this;
  27.         AddRef();
  28.         return S_OK;
  29.     }
  30.  
  31.     return E_NOINTERFACE;
  32. }
  33.  
  34.  
  35. //AddRef
  36. STDMETHODIMP_(ULONG) CDirectInputActionFramework::AddRef()
  37. {
  38.     return InterlockedIncrement(&m_cRef);
  39. }
  40.  
  41.  
  42. //Release
  43. STDMETHODIMP_(ULONG) CDirectInputActionFramework::Release()
  44. {
  45.  
  46.     if (InterlockedDecrement(&m_cRef) == 0)
  47.     {
  48.         delete this;
  49.         return 0;
  50.     }
  51.  
  52.     return m_cRef;
  53. }
  54.  
  55. // Manages auto loading/unloading WINMM.DLL
  56. // There will only be one instance of this class: inside InternalConfigureDevicees.
  57. class CWinMmLoader
  58. {
  59. public:
  60.     CWinMmLoader()
  61.     {
  62.         if (!g_hWinMmDLL)
  63.         {
  64.             g_hWinMmDLL = LoadLibrary(_T("WINMM.DLL"));
  65.             if (g_hWinMmDLL)
  66.             {
  67.                 *(FARPROC*)(&g_fptimeSetEvent) = GetProcAddress(g_hWinMmDLL, "timeSetEvent");
  68.             }
  69.         }
  70.     }
  71.     ~CWinMmLoader()
  72.     {
  73.         if (g_hWinMmDLL)
  74.         {
  75.             /*
  76.              *  Make sure no new callbacks can get scheduled then sleep to 
  77.              *  allow any pending ones to complete.
  78.              */
  79.             g_fptimeSetEvent = NULL;
  80.             Sleep( 40 );
  81.             FreeLibrary(g_hWinMmDLL);
  82.             g_hWinMmDLL = NULL;
  83.         }
  84.     }
  85. };
  86.  
  87.  
  88.  
  89.  
  90. // internal, which api wraps around
  91. static HRESULT InternalConfigureDevices(LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
  92.                                         LPDICONFIGUREDEVICESPARAMSW  lpdiCDParams,
  93.                                         DWORD                        dwFlags,
  94.                                         LPVOID                       pvRefData)
  95. {
  96.     tracescope(__ts, _T("InternalConfigureDevices()\n"));
  97.  
  98.     CWinMmLoader g_WinMmLoadingHelper;  // Automatically call LoadLibrary and FreeLibrary on WINMM.DLL
  99.  
  100.     // check that we're at least 256 colors
  101.     HDC hMemDC = CreateCompatibleDC(NULL);
  102.     if (hMemDC == NULL)
  103.     {
  104.         etrace(_T("Can't get a DC! Exiting.\n"));
  105.         return E_FAIL;
  106.     }
  107.  
  108.     int bpp = GetDeviceCaps(hMemDC, BITSPIXEL);
  109.     DeleteDC(hMemDC);
  110.     if (bpp < 8)
  111.     {
  112.         etrace1(_T("Screen is not at least 8bpp (bpp = %d)\n"), bpp);
  113.         return E_FAIL;
  114.     }
  115.  
  116.     // do it...
  117.     {
  118.         // create the globals
  119.         CUIGlobals uig(
  120.             dwFlags,
  121.             lpdiCDParams->lptszUserNames,
  122.             lpdiCDParams->dwcFormats,
  123.             lpdiCDParams->lprgFormats,
  124.             &(lpdiCDParams->dics),
  125.             lpdiCDParams->lpUnkDDSTarget,
  126.             lpdiCallback,
  127.             pvRefData
  128.         );
  129.         HRESULT hr = uig.GetInitResult();
  130.         if (FAILED(hr))
  131.         {
  132.             etrace(_T("CUIGlobals.Init() failed\n"));
  133.             return hr;
  134.         }
  135.  
  136.         // make sure the flexwnd window class is registered only during possible use
  137.         {
  138.             struct flexwndscope {
  139.                 flexwndscope(CUIGlobals &uig) : m_uig(uig) {CFlexWnd::RegisterWndClass(m_uig.GetInstance());}
  140.                 ~flexwndscope() {CFlexWnd::UnregisterWndClass(m_uig.GetInstance());}
  141.                 CUIGlobals &m_uig;
  142.             } scope(uig);
  143.  
  144.             // create the main window
  145.             CConfigWnd cfgWnd(uig);
  146.             if (!cfgWnd.Create(lpdiCDParams->hwnd))
  147.             {
  148.                 etrace(_T("Failed to create main window\n"));
  149.                 return E_FAIL;
  150.             }
  151.  
  152.             // Initialize the shared tooltip object.
  153.             RECT rc = {0, 0, 0, 0};
  154.             CFlexWnd::s_ToolTip.Create(cfgWnd.m_hWnd, rc, TRUE);
  155.             if (!CFlexWnd::s_ToolTip.m_hWnd)
  156.             {
  157.                 etrace(_T("Failed to create tooltip window\n"));
  158.                 return E_FAIL;
  159.             }
  160.             ::ShowWindow(CFlexWnd::s_ToolTip.m_hWnd, SW_HIDE);  // Hide window by default
  161.  
  162.             // enter message loop
  163.             MSG msg;
  164.             while (GetMessage(&msg, NULL, 0, 0))
  165.             {
  166.                 // If this is a message for the parent window (game window), only dispatch if it's WM_PAINT.
  167.                 if (!cfgWnd.InRenderMode() && msg.hwnd == lpdiCDParams->hwnd && msg.message != WM_PAINT)
  168.                     continue;
  169.                 TranslateMessage(&msg);
  170.                 DispatchMessage(&msg);
  171.             }
  172.         }
  173.  
  174.         CFlexWnd::s_ToolTip.Destroy();
  175.  
  176.         return uig.GetFinalResult();
  177.     }
  178. }
  179.  
  180.  
  181. BOOL AreAcForsGood(LPDIACTIONFORMATW lpAcFors, DWORD dwNumAcFors)
  182. {
  183.     if (lpAcFors == NULL)
  184.         return FALSE;
  185.  
  186.     if (dwNumAcFors < 1)
  187.         return FALSE;
  188.  
  189.     if (lpAcFors->dwNumActions == 0)
  190.         return FALSE;
  191.  
  192.     return TRUE;
  193. }
  194.  
  195.  
  196. //ConfigureDevices
  197. STDMETHODIMP CDirectInputActionFramework::ConfigureDevices(
  198.             LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
  199.             LPDICONFIGUREDEVICESPARAMSW  lpdiCDParams,
  200.             DWORD                        dwFlags,
  201.             LPVOID                       pvRefData)
  202. {
  203.     tracescope(__ts,_T("CDirectInputActionFramework::ConfigureDevices()\n"));
  204.  
  205.     trace(_T("\nConfigureDevices() called...\n\n"));
  206.  
  207.     // check parameters
  208.     if (lpdiCDParams == NULL)
  209.     {
  210.         etrace(_T("NULL params structure passed to ConfigureDevices()\n"));
  211.         return E_INVALIDARG;
  212.     }
  213.  
  214.     // save passed params in case we change 'em
  215.     LPDIACTIONFORMATW lpAcFors = lpdiCDParams->lprgFormats;
  216.     DWORD dwNumAcFors = lpdiCDParams->dwcFormats;
  217.  
  218. #ifdef CFGUI__FORCE_GOOD_ACFORS
  219.  
  220.     if (!AreAcForsGood(lpdiCDParams->lprgFormats, lpdiCDParams->dwcFormats))
  221.     {
  222.         etrace(_T("Passed ActionFormats aren't good...  Using GetTestActionFormats() (just 2 of them).\n"));
  223.         lpdiCDParams->dwcFormats = 2;
  224.         lpdiCDParams->lprgFormats = GetTestActionFormats();
  225.     }
  226.  
  227. #endif
  228.  
  229.     HRESULT hr = InternalConfigureDevices(lpdiCallback, lpdiCDParams, dwFlags, pvRefData);
  230.  
  231.     // restore passed params in case changed
  232.     lpdiCDParams->lprgFormats = lpAcFors;
  233.     lpdiCDParams->dwcFormats = dwNumAcFors;
  234.  
  235.     trace(_T("\n"));
  236.  
  237.     if (FAILED(hr))
  238.         etrace1(_T("ConfigureDevices() failed, returning 0x%08x\n"), hr);
  239.     else
  240.         trace1(_T("ConfigureDevices() suceeded, returning 0x%08x\n"), hr);
  241.  
  242.     trace(_T("\n"));
  243.  
  244.     return hr;
  245. }
  246.  
  247.  
  248. //constructor
  249. CDirectInputActionFramework::CDirectInputActionFramework()
  250. {
  251.     //set ref count
  252.     m_cRef = 1;
  253. }
  254.  
  255.  
  256. //destructor
  257. CDirectInputActionFramework::~CDirectInputActionFramework()
  258. {
  259.     // not necessary to cleanup action format here
  260. }
  261.